<?php

namespace App\Http\Controllers\Front;

use App\Model\MaiBaoBill;
use App\Model\MaibaoOrder;
use App\Model\MaibaoQueue;
use App\Model\SystemMsg;
use App\Model\UserGrade;
use App\Model\UserRecharge;
use App\Model\UserTemplate;
use App\Model\UserTemplateClone;
use App\Model\UserTemplateOrder;
use App\Model\UserWalletRecordLog;
use App\Model\UserWeixinPayCallBackErrorLog;
use App\Model\VipFeeConfig;
use App\Model\WeChat;
use App\Tool\Util;
use App\User;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use Yansongda\Pay\Pay;

class PayController extends Controller
{
	/**
	 * @var User
	 */
	private $user;
	/**
	 * @var 公众号支付配置
	 */
	private $payConfig;

	public function __construct()
	{
		$this->user = Auth::user();

		$conf = \Config::get('wechat.payment.default');

		$this->payConfig = [
			'app_id' => $conf['app_id'],
			'mch_id' => $conf['mch_id'],
			'key' => $conf['key'],
			'notify_url' => env('apiUrl') . '/front/jspay',
		];
	}

	public function jssdk()
	{
		$app = WeChat::getWeChatOfficialAccount();
		$url = env('weixinUrl') . '/#/pay';
		$app->jssdk->setUrl($url);
		$jssdk = $app->jssdk->buildConfig(array('chooseWXPay'), false, false, false);
		return $this->renderJson(['jssdk' => $jssdk]);
	}

	/**
	 *
	 */
	public function pay(Request $request)
	{
		$this->validate($request, [
			'biz_type' => 'required',
			'money' => 'required',//实付款金额
			'wallet' => 'required',//是否勾选钱包
			'pay_type' => 'required',//支付方式 0钱包 1微信 2支付宝
			'target_id' => 'required',//会员配置id 克隆网页personal_page_template_clone:id 脉宝个数
		], [
			'biz_type.required' => 'biz_type不能为空',
			'money.required' => 'money不能为空',
			'wallet.required' => 'wallet不能为空',
			'pay_type.required' => 'pay_type不能为空',
			'target_id.required' => 'target_id不能为空'
		]);
		$biz_type = $request->input("biz_type");
		$money = $request->input("money");
		$wallet = $request->input("wallet");
		$pay_type = $request->input("pay_type");
		$target_id = $request->input("target_id");

		switch ($biz_type) {
			//开会员
			case 1:
				return $this->vip($money, $wallet, $pay_type, $target_id);
			//克隆
			case 2:
				return $this->clonepage($money, $wallet, $pay_type, $target_id);
			//脉宝
			case 3:
				return $this->maibao($money, $wallet, $pay_type, $target_id);
			default:
				return $this->fail('biz_type error');
		}
	}

	//微信支付通知
	public function wxnotify()
	{
		$wechat = Pay::wechat($this->payConfig);
//        file_put_contents('./1.txt', json_encode($wechat));

		try {
			\DB::beginTransaction();
			$data = $wechat->verify();
			$callback = $data->all();
			if ($callback['result_code'] === 'SUCCESS' && $callback['return_code'] === 'SUCCESS') {
				switch ($callback['attach']) {
					//开会员
					case 1:
						$this->vipNotify($callback);
						break;
					//克隆
					case 2:
						$this->clonepageNotify($callback);
						break;
					//脉宝
					case 3:
						$this->maibaoNotify($callback);
						break;
					default:
						break;
				}
			}
			\DB::commit();
		} catch (\Exception $e) {
			\DB::rollBack();
			// 记录错误日志
			$error_log = new UserWeixinPayCallBackErrorLog();
			$error_log->insert(['error' => $e->getMessage() . $callback['out_trade_no']]);
			Log::error($e->getMessage() . "-{$callback['attach']}-" . $callback['out_trade_no']);
		}
		return $wechat->success();
	}

	//开会员
	private function vip($money, $wallet, $pay_type, $target_id)
	{
		$vipFeeConfig = VipFeeConfig::where('id', $target_id)->first();
		if (!$vipFeeConfig) {
			return $this->fail('target_id error');
		}

		//计算应付金额
		$wallet_money = 0; //钱包抵扣金额
		$true_money = 0;    //在线应付金额
		if ($wallet) {
			if ($this->user->money >= $vipFeeConfig->money) {
				$wallet_money = $vipFeeConfig->money;
			} else {
				$true_money = round($vipFeeConfig->money - $this->user->money, 2);
				$wallet_money = $this->user->money;
			}
		} else {
			$true_money = $vipFeeConfig->money;
		}

		if ($money != $true_money) {
			return $this->fail('money error');
		}
		//全部余额支付
		if ($true_money == 0) {
			if (!password_verify(\request('pwd'), $this->user->payment_password)){
				return $this->fail('支付密码错误');
			}
			try {
				\DB::beginTransaction();

				$grade = UserGrade::where('user_id', $this->user->id)->first();
				$overed_at = Carbon::now()->addMonths($vipFeeConfig->months);
				if ($grade) {
					if ($grade->overed_at && Carbon::parse($grade->overed_at)->timestamp >= Carbon::now()->timestamp) {
						$overed_at = Carbon::parse($grade->overed_at)->addMonths($vipFeeConfig->months);
					}
					$grade->last_money = $wallet_money;
					$grade->vip_fee_config_id = $vipFeeConfig->id;
					$grade->vip_fee_config_comment = $vipFeeConfig->name;
					$grade->overed_at = $overed_at;
					$grade->last_at = $overed_at;
					$grade->updated_at = Carbon::now();
					$ug = $grade->save();
					if (!$ug) throw new \Exception("UserGrade save error");
				} else {
					$ug = UserGrade::insert([
						'user_id' => $this->user->id,
						'last_money' => $wallet_money,
						'vip_fee_config_id' => $vipFeeConfig->id,
						'vip_fee_config_comment' => $vipFeeConfig->name,
						'created_at' => Carbon::now(),
						'overed_at' => $overed_at,
						'last_at' => $overed_at,
					]);
					if (!$ug) throw new \Exception("UserGrade save error");
				}
				//充值记录
				$out_trade_no = time();
				$urid = UserRecharge::insertGetId([
					'user_id' => $this->user->id,
					'money' => $wallet_money,
					'vip_fee_config_id' => $vipFeeConfig->id,
					'last_money' => $wallet_money,
					'overed_at' => Carbon::now()->addMonths($vipFeeConfig->months),
					'last_at' => Carbon::now()->addMonths($vipFeeConfig->months),
					'vip_fee_config_comment' => $vipFeeConfig->name,
					'is_pay' => 1,
					'pay_time' => Carbon::now(),
					'pay_type' => '余额支付',
					'out_trade_no' => $out_trade_no,
					'created_at' => Carbon::now(),
				]);
				if (!$urid) throw new \Exception("UserRecharge save error");
				//会员钱包记录
				$uwid = UserWalletRecordLog::insert([
					'type' => 7,
					'income_type' => 0,
					'user_id' => $this->user->id,
					'money' => $wallet_money,
					'relation_id' => $urid,
					'describe' => $vipFeeConfig->name,
					'created_at' => Carbon::now(),
				]);
				if (!$uwid) throw new \Exception("UserWalletRecordLog save error");

                // 分销返佣和企业提成
                $u = new UnifiedReturnCommissionController();
                $u->UnifiedReturnCommission($this->user->id, $out_trade_no);

				$this->user->decrement('money', $wallet_money);
				\DB::commit();
				return $this->renderJson(['pay_type' => $pay_type, 'params' => '']);
			} catch (\Exception $e) {
				\DB::rollBack();
				Log::error($e);
				return $this->fail("余额支付失败");
			}
		}

		//部分余额 部分在线支付
		$orderNum = Util::getOrderNum();
		$params = null;
		$pay_type_name = '';
		if ($pay_type == 1) {
			$pay_type_name = '公众号支付';
			$params = Pay::wechat($this->payConfig)->mp([
				'body' => $vipFeeConfig->name,
				'out_trade_no' => $orderNum,
				'total_fee' => $true_money * 100,
				'attach' => 1,
				'openid' => $this->user->detail->open_id,
			]);
		}
		if (!$params) {
			$this->fail('下单失败');
		}
		$grade = UserGrade::where('user_id', $this->user->id)->first();

		$overAt = Carbon::now();
		if ($grade && $grade->overed_at && Carbon::parse($grade->overed_at)->timestamp >= Carbon::now()->timestamp) {
			$overAt = Carbon::parse($grade->overed_at);
		}
		$overAt = $overAt->addMonths($vipFeeConfig->months);
		$urid = UserRecharge::insert([
			'user_id' => $this->user->id,
			'money' => $vipFeeConfig->money,
			'vip_fee_config_id' => $vipFeeConfig->id,
			'last_money' => $vipFeeConfig->money,
			'overed_at' => $overAt,
			'last_at' => $overAt,
			'vip_fee_config_comment' => $vipFeeConfig->name,
			'is_pay' => 0,
			'pay_type' => $pay_type_name,
			'out_trade_no' => $orderNum,
			'created_at' => Carbon::now(),
		]);
		if (!$urid) {
			return $this->fail('订单创建失败');
		}
		return $this->renderJson(['pay_type' => $pay_type, 'params' => $params]);
	}

	//克隆
	public function clonepage($money, $wallet, $pay_type, $target_id)
	{
		$clone = UserTemplateClone::find($target_id);

		if (!$clone) {
			return $this->fail('target_id error');
		}
		if ($clone->is_paid == 1) {
			return $this->fail('你已经支付过了', 200);
		}
		if ($clone->amount <= 0) {
			return $this->fail('该模板不需要支付');
		}
		$temp = UserTemplate::find($clone->template_id);
		if (!$temp) {
			return $this->fail('该模板不存在');
		}

		//计算应付金额
		$wallet_money = 0; //钱包抵扣金额
		$true_money = 0;    //在线应付金额
		if ($wallet) {
			if ($this->user->money >= $clone->amount) {
				$wallet_money = $clone->amount;
			} else {
				$true_money = round($clone->amount - $this->user->money, 2);
				$wallet_money = $this->user->money;
			}
		} else {
			$true_money = $clone->amount;
		}

		if ($money != $true_money) {
			return $this->fail('money error');
		}
		//全部余额支付
		if ($true_money == 0) {
			if (!password_verify(\request('pwd'), $this->user->payment_password)){
				return $this->fail('支付密码错误');
			}
			try {
				\DB::beginTransaction();
				//扣款
				$this->user->decrement('money', $wallet_money);
				//会员钱包记录
				UserWalletRecordLog::insert([
					'type' => 6,
					'income_type' => 0,
					'user_id' => $this->user->id,
					'money' => $wallet_money,
					'relation_id' => $target_id,
					'describe' => "克隆《{$temp->title}》",
					'created_at' => Carbon::now(),
				]);
				$to = User::where('id', $temp->user_id)->lockForUpdate()->first();
				//入款
				$to->increment('custom_income', $wallet_money);
				$to->increment('money', $wallet_money);
				UserWalletRecordLog::insert([
					'type' => 2,
					'income_type' => 1,
					'user_id' => $temp->user_id,
					'money' => $wallet_money,
					'relation_id' => $target_id,
					'describe' => "《{$temp->title}》 被克隆",
					'created_at' => Carbon::now(),
				]);
				$clone->is_paid = 1;
				$clone->save();
				SystemMsg::add($to->id,SystemMsg::CLONE,"《{$temp->title}》 被克隆","《{$temp->title}》 被克隆",$wallet_money);
				\DB::commit();
				return $this->renderJson(['pay_type' => $pay_type, 'params' => '']);
			} catch (\Exception $e) {
				\DB::rollBack();
				return $this->fail('购买失败!请稍后重试');
			}
		}
		//部分余额 部分在线支付
		$orderNum = Util::getOrderNum();
		$params = null;
		$pay_type_name = '';
		if ($pay_type == 1) {
			$pay_type_name = '公众号支付';
			$params = Pay::wechat($this->payConfig)->mp([
				'body' => '网页克隆',
				'out_trade_no' => $orderNum,
				'total_fee' => $true_money * 100,
				'attach' => 2,
				'openid' => $this->user->detail->open_id,
			]);
		}
		if (!$params) {
			$this->fail('下单失败');
		}
		$pg = \DB::table('personal_page_order')->insert([
			'user_id' => $this->user->id,
			'amount' => $clone->amount,
			'clone_id' => $target_id,
			'order_at' => Carbon::now(),
			'out_trade_no' => $orderNum,
			'paid_type' => $pay_type_name,
			'created_at' => Carbon::now(),
		]);

		if (!$pg) {
			return $this->fail('克隆订单创建失败');
		}
		return $this->renderJson(['pay_type' => $pay_type, 'params' => $params]);

	}

	//maibao
	private function maibao($money, $wallet, $pay_type, $target_id)
	{
		if ($target_id <= 0) {
			return $this->fail('金额错误');
		}
		if ($target_id < 1000) {
			return $this->fail('充值金额不能小于1000');
		}

		//计算应付金额
		$wallet_money = 0; //钱包抵扣金额
		$true_money = 0;    //在线应付金额
		if ($wallet) {
			if ($this->user->money >= $target_id) {
				$wallet_money = $target_id;
			} else {
				$true_money = round($target_id - $this->user->money, 2);
				$wallet_money = $this->user->money;
			}
		} else {
			$true_money = $target_id;
		}

		if ($money != $true_money) {
			return $this->fail('money error');
		}

		//全部余额支付
		if ($true_money == 0) {
			if (!password_verify(\request('pwd'), $this->user->payment_password)){
				return $this->fail('支付密码错误');
			}
			try {
				\DB::beginTransaction();
				$mbid = MaiBaoBill::insertGetId([
					'user_id' => $this->user->id,
					'type' => 1,
					'title' => '钱包充值',
					'amount' => $wallet_money,
					'cate' => 4,
					'created_at' => Carbon::now()
				]);
				$moid = MaibaoOrder::insert([
					'user_id' => $this->user->id,
					'bill_id' => $mbid,
					'amount' => $wallet_money,
					'order_at' => Carbon::now(),
					'is_paid' => 1,
					'paid_at' => Carbon::now(),
					'paid_type' => '余额支付',
					'out_trade_no' => time(),
					'ip' => \request()->getClientIp(),
					'created_at' => Carbon::now(),
					'status' => 'paid',
				]);
				MaibaoQueue::insert([
					'user_id' => $this->user->id,
					'amount' => $wallet_money,
					'ip' => \request()->getClientIp(),
					'created_at' => Carbon::now()
				]);
				UserWalletRecordLog::insert([
					'type' => 9,
					'income_type' => 0,
					'user_id' => $this->user->id,
					'money' => $wallet_money,
					'relation_id' => $moid,
					'describe' => "脉宝充值",
					'created_at' => Carbon::now(),
				]);
				$this->user->decrement('money', $wallet_money);
				$this->user->increment('maibao', $wallet_money);
				\DB::commit();
				return $this->renderJson(['pay_type' => $pay_type, 'params' => '']);
			} catch (\Exception $e) {
				\DB::rollBack();
				return $this->fail('脉宝充值失败!请稍后重试');
			}
		}

		//部分余额 部分在线支付
		$orderNum = Util::getOrderNum();
		$params = null;
		$pay_type_name = '';
		if ($pay_type == 1) {
			$pay_type_name = '公众号支付';
			$params = Pay::wechat($this->payConfig)->mp([
				'body' => '脉宝充值' . $target_id,
				'out_trade_no' => $orderNum,
				'total_fee' => $true_money * 100,
				'attach' => 3,
				'openid' => $this->user->detail->open_id,
			]);
		}
		if (!$params) {
			$this->fail('下单失败');
		}

		$mo = MaibaoOrder::insert([
			'user_id' => $this->user->id,
			'amount' => $target_id,
			'order_at' => Carbon::now(),
			'paid_type' => $pay_type_name,
			'out_trade_no' => $orderNum,
			'ip' => \request()->getClientIp(),
			'created_at' => Carbon::now(),
		]);

		if (!$mo) {
			return $this->fail('脉宝订单创建失败');
		}
		return $this->renderJson(['pay_type' => $pay_type, 'params' => $params]);
	}

	/**
	 * 开通会员 notify
	 */
	public function vipNotify($data)
	{
		$rechargeObj = UserRecharge::where('out_trade_no', $data['out_trade_no'])->where('is_pay', '0')->first();

		if ($rechargeObj) {
			$rechargeObj->is_pay = 1;
			$rechargeObj->status = 1;
			$rechargeObj->pay_time = Carbon::now();
			$rechargeObj->weixin_total_fee = $data['total_fee'] * 0.01;
			if (!$rechargeObj->save()) throw new \Exception('状态修改失败');

			$wallteMoney = 0;
			if ($rechargeObj->weixin_total_fee != $rechargeObj->money) {
				$wallteMoney = round($rechargeObj->money - $rechargeObj->weixin_total_fee, 2);
			}

			$userInfo = User::where('id', $rechargeObj->user_id)->first(); // 查询用信息
			//含有余额支付
			if ($wallteMoney > 0) {
				$userInfo->decrement('money', $wallteMoney);

				//会员钱包记录
				$uwid = UserWalletRecordLog::insert([
					'type' => 7,
					'income_type' => 0,
					'user_id' => $rechargeObj->user_id,
					'money' => $wallteMoney,
					'relation_id' => $rechargeObj->id,
					'describe' => $rechargeObj->vip_fee_config_comment,
					'created_at' => Carbon::now(),
				]);
				if (!$uwid) throw new \Exception("UserWalletRecordLog save error");
			}
			$grade = UserGrade::where('user_id', $rechargeObj->user_id)->first();
			if ($grade) {
				$grade->last_money = $rechargeObj->money;
				$grade->vip_fee_config_id = $rechargeObj->vip_fee_config_id;
				$grade->vip_fee_config_comment = $rechargeObj->vip_fee_config_comment;
				$grade->overed_at = $rechargeObj->overed_at;
				$grade->last_at = $rechargeObj->overed_at;
				$grade->updated_at = Carbon::now();
				$ug = $grade->save();
				if (!$ug) throw new \Exception("UserGrade save error");
			} else {
				$ug = UserGrade::insert([
					'user_id' => $rechargeObj->user_id,
					'last_money' => $rechargeObj->money,
					'vip_fee_config_id' => $rechargeObj->vip_fee_config_id,
					'vip_fee_config_comment' => $rechargeObj->vip_fee_config_comment,
					'created_at' => Carbon::now(),
					'overed_at' => $rechargeObj->overed_at,
					'last_at' => $rechargeObj->overed_at,
				]);
				if (!$ug) throw new \Exception("UserGrade save error");
			}

			// 返佣和企业提成
			$u = new UnifiedReturnCommissionController();
			$u->UnifiedReturnCommission($rechargeObj->user_id, $rechargeObj->out_trade_no);
		}
	}

	/**
	 * 克隆 notify
	 */
	public function clonepageNotify($data)
	{
		$order = UserTemplateOrder::where('out_trade_no', $data['out_trade_no'])->where('is_paid', 0)->first();
		if ($order) {
			//支付成功
			$order->is_paid = 1;
			$order->paid_at = Carbon::now();
			$order->status = 'paid';
			$order->callback_total_fee = $data['total_fee'] * 0.01;

			$wallteMoney = 0;
			if ($order->callback_total_fee != $order->amount) {
				$wallteMoney = round($order->amount - $order->callback_total_fee, 2);
			}

			$userInfo = User::where('id', $order->user_id)->first(); // 查询用信息
			$clone = UserTemplateClone::find($order->clone_id);
			$temp = UserTemplate::find($clone->template_id);
			//含有余额支付
			if ($wallteMoney > 0) {
				$userInfo->decrement('money', $wallteMoney);
				//会员钱包记录
				UserWalletRecordLog::insert([
					'type' => 6,
					'income_type' => 0,
					'user_id' => $order->user_id,
					'money' => $wallteMoney,
					'relation_id' => $order->id,
					'describe' => "克隆《{$temp->title}》",
					'created_at' => Carbon::now(),
				]);

			}
			$to = User::where('id', $temp->user_id)->lockForUpdate()->first();
			//入款
			$to->increment('custom_income', $order->amount);
			$to->increment('money', $order->amount);
			UserWalletRecordLog::insert([
				'type' => 2,
				'income_type' => 1,
				'user_id' => $temp->user_id,
				'money' => $order->amount,
				'relation_id' => $order->id,
				'describe' => "《{$temp->title}》 被克隆",
				'created_at' => Carbon::now(),
			]);
			$order->save();
			SystemMsg::add($to->id,SystemMsg::CLONE,"《{$temp->title}》 被克隆","《{$temp->title}》 被克隆",$order->amount);
		}
	}

	/**
	 * 脉宝 notify
	 */
	public function maibaoNotify($data)
	{
		$order = MaibaoOrder::where('out_trade_no', $data['out_trade_no'])->where('is_paid', 0)->first();

		if ($order) {
			$order->is_paid = 1;
			$order->paid_at = Carbon::now();
			$order->status = 'paid';
			$order->callback_total_fee = $data['total_fee'] * 0.01;
			$wallteMoney = 0;
			if ($order->callback_total_fee != $order->amount) {
				$wallteMoney = round($order->amount - $order->callback_total_fee, 2);
			}

			$userInfo = User::where('id', $order->user_id)->first(); // 查询用信息
			//含有余额支付
			if ($wallteMoney > 0) {
				$userInfo->decrement('money', $wallteMoney);
				//会员钱包记录
				UserWalletRecordLog::insert([
					'type' => 9,
					'income_type' => 0,
					'user_id' => $order->user_id,
					'money' => $wallteMoney,
					'relation_id' => $order->id,
					'describe' => "脉宝充值",
					'created_at' => Carbon::now(),
				]);

			}
			$mbid = MaiBaoBill::insertGetId([
				'user_id' => $order->user_id,
				'type' => 1,
				'title' => '钱包充值',
				'amount' => $order->amount,
				'cate' => 4,
				'created_at' => Carbon::now()
			]);
			$order->bill_id = $mbid;

			MaibaoQueue::insert([
				'user_id' => $order->user_id,
				'amount' => $order->amount,
				'ip' => $order->ip,
				'created_at' => Carbon::now()
			]);

			$userInfo->increment('maibao', $order->amount);

			$order->save();
		}

	}

}
